4 關注者

收集表格輸入

有時您需要在單一表單中處理多個相同種類的模型。例如,多個設定,其中每個設定都儲存為名稱-值對,並由 Setting active record 模型表示。這種表單也常被稱為「表格輸入」。與此相反,處理不同種類的不同模型,在 具有多個模型的複雜表單 章節中處理。

以下說明如何使用 Yii 實作表格輸入。

有三種不同的情況需要涵蓋,必須稍有不同的處理方式

  • 更新資料庫中固定的記錄集
  • 建立動態的新記錄集
  • 在同一個頁面更新、建立和刪除記錄

與之前解釋的單一模型表單相反,我們現在正在使用模型陣列。此陣列會傳遞到視圖,以表格樣式顯示每個模型的輸入欄位,我們將使用 yii\base\Model 的輔助方法,允許一次載入和驗證多個模型

更新固定的記錄集

讓我們從控制器動作開始

<?php

namespace app\controllers;

use yii\web\Controller;
use app\models\Setting;

class SettingsController extends Controller
{
    // ...

    public function actionUpdate()
    {
        $settings = Setting::find()->indexBy('id')->all();

        if ($this->request->isPost) {
            if (Setting::loadMultiple($settings, $this->request->post()) && Setting::validateMultiple($settings)) {
                foreach ($settings as $setting) {
                    $setting->save(false);
                }
                return $this->redirect('index');
            }
        }

        return $this->render('update', ['settings' => $settings]);
    }
}

在上面的程式碼中,我們在使用 indexBy() 從資料庫檢索模型時,填充一個以模型主鍵索引的陣列。這些稍後將用於識別表單欄位。Model::loadMultiple() 使用來自 POST 的表單資料填充多個模型,而 Model::validateMultiple() 一次驗證所有模型。由於我們之前已經驗證了模型,使用 validateMultiple(),我們現在傳遞 false 作為參數給 save(),以避免再次執行驗證。

現在是在 update 視圖中的表單

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

$form = ActiveForm::begin();

foreach ($settings as $id => $setting) {
    echo $form->field($setting, "[$id]value")->label($setting->name);
}

echo Html::submitButton('Save');

ActiveForm::end();

在這裡,對於每個設定,我們都呈現名稱和帶有值的輸入。重要的是要為輸入名稱添加適當的索引,因為這就是 Model::loadMultiple() 確定要用哪些值填充哪個模型的方式。

建立動態的新記錄集

建立新記錄與更新類似,除了我們實例化模型的部分

public function actionCreate()
{
    $settings = [];
    if ($this->request->isPost) {
        $count = count($this->request->post($setting->tableName()));
        for ($i = 0; $i < $count; $i++) {
            $settings[$i] = new Setting();
        }
        if (Setting::loadMultiple($settings, $this->request->post()) && Setting::validateMultiple($settings)) {
            foreach ($settings as $setting) {
                $setting->save(false);
            }
            return $this->redirect('index');
        }
    }
    $settings[] = new Setting();

    return $this->render('create', ['settings' => $settings]);
}

在這裡,我們建立一個初始的 $settings 陣列,預設包含一個模型,以便始終在視圖中至少顯示一個文字欄位。此外,我們為可能收到的每一行輸入添加更多模型。

在視圖中,您可以使用 JavaScript 動態添加新的輸入行。

在同一個頁面組合更新、建立和刪除

注意:本節正在開發中。

目前尚無內容。

待辦事項

發現錯字或您認為此頁面需要改進?
在 github 上編輯 !